package com.tiktok.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tiktok.dto.request.VideoUploadRequest;
import com.tiktok.entity.User;
import com.tiktok.entity.UserVideoView;
import com.tiktok.entity.Video;
import com.tiktok.entity.VideoLike;
import com.tiktok.mapper.UserVideoViewMapper;
import com.tiktok.mapper.VideoLikeMapper;
import com.tiktok.mapper.VideoMapper;
import com.tiktok.service.UserService;
import com.tiktok.service.VideoService;
import com.tiktok.utils.UserContext;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 视频服务实现类
 */
@Service
@RequiredArgsConstructor
public class VideoServiceImpl extends ServiceImpl<VideoMapper, Video> implements VideoService {

    private final VideoLikeMapper videoLikeMapper;
    private final UserVideoViewMapper userVideoViewMapper;
    private final UserService userService;
    private static final Logger log = LoggerFactory.getLogger(VideoServiceImpl.class);

    @Override
    public Page<Video> getRecommendVideos(Long userId, int current, int size) {
        Page<Video> page = new Page<>(current, size);
        
        if (userId != null) {
            // 直接使用Mapper的安全查询方法
            List<Video> videos = baseMapper.selectRecommendVideos(userId, page);
            page.setRecords(videos);
            
            // 设置作者信息和点赞状态
            for (Video video : videos) {
                setVideoAuthorAndLikeStatus(video, userId);
            }
        } else {
            // 未登录用户，显示所有正常状态的视频
            LambdaQueryWrapper<Video> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Video::getStatus, 1)
                   .orderByDesc(Video::getLikeCount, Video::getCreateTime);
            page = page(page, wrapper);
            
            // 设置作者信息和点赞状态
            for (Video video : page.getRecords()) {
                setVideoAuthorAndLikeStatus(video, null);
            }
        }
        
        return page;
    }

    @Override
    public Page<Video> getUserVideos(Long userId, int current, int size) {
        Page<Video> page = new Page<>(current, size);
        List<Video> videos = baseMapper.selectUserVideos(userId, page);
        
        // 设置作者信息和点赞状态
        for (Video video : videos) {
            setVideoAuthorAndLikeStatus(video, UserContext.getUserId());
        }
        
        page.setRecords(videos);
        // 查询总数
        LambdaQueryWrapper<Video> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Video::getUserId, userId).eq(Video::getStatus, 1);
        long total = baseMapper.selectCount(wrapper);
        page.setTotal(total);
        return page;
    }

    @Override
    @Transactional
    public void publishVideo(VideoUploadRequest request) {
        Long userId = UserContext.getUserId();
        if (userId == null) {
            throw new RuntimeException("用户未登录");
        }

        Video video = new Video();
        video.setUserId(userId);
        video.setTitle(request.getTitle());
        video.setDescription(request.getDescription());
        video.setVideoUrl(request.getVideoUrl());
        video.setCoverUrl(request.getCoverUrl());
        video.setDuration(request.getDuration());
        video.setFileSize(request.getFileSize());
        video.setWidth(request.getWidth());
        video.setHeight(request.getHeight());
        video.setStatus(1);

        save(video);
    }

    @Override
    @Transactional
    public void deleteVideo(Long videoId) {
        Long userId = UserContext.getUserId();
        if (userId == null) {
            throw new RuntimeException("用户未登录");
        }

        Video video = getById(videoId);
        if (video == null) {
            throw new RuntimeException("视频不存在");
        }

        if (!video.getUserId().equals(userId)) {
            throw new RuntimeException("无权限删除此视频");
        }

        // 软删除：设置状态为0
        video.setStatus(0);
        updateById(video);
    }

    @Override
    @Transactional
    public void likeVideo(Long videoId) {
        Long userId = UserContext.getUserId();
        if (userId == null) {
            throw new RuntimeException("用户未登录");
        }

        Video video = getById(videoId);
        if (video == null) {
            throw new RuntimeException("视频不存在");
        }

        // 查询是否已点赞
        LambdaQueryWrapper<VideoLike> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(VideoLike::getUserId, userId)
               .eq(VideoLike::getVideoId, videoId);
        VideoLike existingLike = videoLikeMapper.selectOne(wrapper);

        if (existingLike == null) {
            // 新增点赞
            VideoLike videoLike = new VideoLike();
            videoLike.setUserId(userId);
            videoLike.setVideoId(videoId);
            videoLike.setStatus(1);
            videoLikeMapper.insert(videoLike);
            
            // 增加点赞数
            baseMapper.increaseLikeCount(videoId);
        } else {
            // 切换点赞状态
            if (existingLike.getStatus() == 1) {
                // 取消点赞
                existingLike.setStatus(0);
                videoLikeMapper.updateById(existingLike);
                baseMapper.decreaseLikeCount(videoId);
            } else {
                // 重新点赞
                existingLike.setStatus(1);
                videoLikeMapper.updateById(existingLike);
                baseMapper.increaseLikeCount(videoId);
            }
        }
    }

    @Override
    @Transactional
    public void recordVideoView(Long videoId) {
        Long userId = UserContext.getUserId();
        if (userId == null) {
            return;
        }

        // 检查是否已观看过
        LambdaQueryWrapper<UserVideoView> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserVideoView::getUserId, userId)
               .eq(UserVideoView::getVideoId, videoId);
        UserVideoView existingView = userVideoViewMapper.selectOne(wrapper);

        if (existingView == null) {
            // 记录观看
            UserVideoView userVideoView = new UserVideoView();
            userVideoView.setUserId(userId);
            userVideoView.setVideoId(videoId);
            userVideoView.setViewTime(LocalDateTime.now());
            userVideoViewMapper.insert(userVideoView);

            // 增加播放数
            baseMapper.increaseViewCount(videoId);
        }
    }

    @Override
    public Video getPreviousVideo(Long userId, Long currentVideoId) {
        // 使用更高效的查询方式
        Video currentVideo = getById(currentVideoId);
        if (currentVideo == null) {
            return null;
        }
        
        // 如果有用户ID，先获取已观看的视频ID列表
        List<Long> viewedVideoIds = null;
        if (userId != null) {
            LambdaQueryWrapper<UserVideoView> viewWrapper = new LambdaQueryWrapper<>();
            viewWrapper.eq(UserVideoView::getUserId, userId);
            viewWrapper.select(UserVideoView::getVideoId);
            List<UserVideoView> viewedList = userVideoViewMapper.selectList(viewWrapper);
            viewedVideoIds = viewedList.stream().map(UserVideoView::getVideoId).collect(java.util.stream.Collectors.toList());
        }
        
        // 查询当前视频之前的视频（按点赞数和创建时间排序）
        LambdaQueryWrapper<Video> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Video::getStatus, 1);
        
        // 排除已观看的视频
        if (viewedVideoIds != null && !viewedVideoIds.isEmpty()) {
            wrapper.notIn(Video::getId, viewedVideoIds);
        }
        
        // 查找比当前视频点赞数更高的，或点赞数相等但创建时间更早的视频
        wrapper.and(w -> w
            .gt(Video::getLikeCount, currentVideo.getLikeCount())
            .or(w2 -> w2.eq(Video::getLikeCount, currentVideo.getLikeCount())
                        .lt(Video::getCreateTime, currentVideo.getCreateTime()))
        );
        
        wrapper.orderByDesc(Video::getLikeCount, Video::getCreateTime);
        wrapper.last("LIMIT 1");
        
        Video previousVideo = getOne(wrapper);
        if (previousVideo != null) {
            setVideoAuthorAndLikeStatus(previousVideo, userId);
        }
        return previousVideo;
    }

    @Override
    public Video getNextVideo(Long userId, Long currentVideoId) {
        // 使用更高效的查询方式
        Video currentVideo = getById(currentVideoId);
        if (currentVideo == null) {
            return null;
        }
        
        // 如果有用户ID，先获取已观看的视频ID列表
        List<Long> viewedVideoIds = null;
        if (userId != null) {
            LambdaQueryWrapper<UserVideoView> viewWrapper = new LambdaQueryWrapper<>();
            viewWrapper.eq(UserVideoView::getUserId, userId);
            viewWrapper.select(UserVideoView::getVideoId);
            List<UserVideoView> viewedList = userVideoViewMapper.selectList(viewWrapper);
            viewedVideoIds = viewedList.stream().map(UserVideoView::getVideoId).collect(java.util.stream.Collectors.toList());
        }
        
        // 查询当前视频之后的视频（按点赞数和创建时间排序）
        LambdaQueryWrapper<Video> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Video::getStatus, 1);
        
        // 排除已观看的视频
        if (viewedVideoIds != null && !viewedVideoIds.isEmpty()) {
            wrapper.notIn(Video::getId, viewedVideoIds);
        }
        
        // 查找比当前视频点赞数更低的，或点赞数相等但创建时间更晚的视频
        wrapper.and(w -> w
            .lt(Video::getLikeCount, currentVideo.getLikeCount())
            .or(w2 -> w2.eq(Video::getLikeCount, currentVideo.getLikeCount())
                        .gt(Video::getCreateTime, currentVideo.getCreateTime()))
        );
        
        wrapper.orderByDesc(Video::getLikeCount, Video::getCreateTime);
        wrapper.last("LIMIT 1");
        
        Video nextVideo = getOne(wrapper);
        if (nextVideo != null) {
            setVideoAuthorAndLikeStatus(nextVideo, userId);
        }
        return nextVideo;
    }

    /**
     * 设置视频作者信息和点赞状态
     */
    private void setVideoAuthorAndLikeStatus(Video video, Long userId) {
        if (video == null) {
            return;
        }
        
        // 设置作者信息
        try {
            User author = userService.getById(video.getUserId());
            if (author != null) {
                User authorInfo = new User();
                authorInfo.setId(author.getId());
                authorInfo.setNickname(author.getNickname());
                authorInfo.setAvatar(author.getAvatar());
                video.setAuthor(authorInfo);
            }
        } catch (Exception e) {
            log.warn("设置视频作者信息失败, videoId: {}", video.getId(), e);
        }

        // 设置点赞状态
        try {
            if (userId != null) {
                LambdaQueryWrapper<VideoLike> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(VideoLike::getUserId, userId)
                       .eq(VideoLike::getVideoId, video.getId())
                       .eq(VideoLike::getStatus, 1);
                VideoLike videoLike = videoLikeMapper.selectOne(wrapper);
                video.setIsLiked(videoLike != null);
            } else {
                video.setIsLiked(false);
            }
        } catch (Exception e) {
            log.warn("设置视频点赞状态失败, videoId: {}, userId: {}", video.getId(), userId, e);
            video.setIsLiked(false);
        }
    }
} 